package ar.com.ford.it.fullEconomics.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import com.ford.it.logging.ILogger;
import com.ford.it.logging.Level;
import com.ford.it.logging.LogFactory;

/**
 * MailSender <br>
 * Envia mails en formato HTML incluyendo el logo Ford. Crea el cuerpo del mail
 * a partir de un archivo template. Antes de crear una instancia debe
 * inicializarse llamando al metodo init(...), pasandole la direccion del
 * servidor SMTP y el path de la aplicacion. Dentro del path de la aplicacion
 * debe existir la carpeta <code>mail</code> conteniendo el logo Ford
 * (LogoFord.gif) y los archivos template.
 * 
 * @author Aji
 */
public class MailSender {
    private static final String CLASS_NAME = MailSender.class.getName();
    private static final ILogger log = LogFactory.getInstance().getLogger(
            CLASS_NAME);

    /**
     * Enviar un mail creado a partir de un archivo template. El template se
     * rellena con los valores pasados en templateValues, usando la clase
     * java.text.MessageFormat
     * 
     * @see <a
     * href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html">MessageFormat</a>
     * @param from
     * Remitente. Si es null se usa el usuario de la base.
     * @param add_to
     * CDS de los Destinatario(s) separados por coma
     * @param subject
     * Asunto
     * @param bodyTemplateFile
     * Archivo template para generar el cuerpo del mail
     * @param templateValues
     * Valores con los que se rellena el template del cuerpo del mail
     */
    public void sendMail(String from, String add_to, String subject,
                         String bodyTemplateFile, Object[] templateValues) {
        String METHOD_NAME = "sendMail";
        log.entering(CLASS_NAME, METHOD_NAME);

        String body, template;
        String[] address_to = add_to.split(",");

        try {
            // Cargar archivo template
            File file = new File(ReConfigProvider.getAppPath() + File.separator
                    + "mail" + File.separator + bodyTemplateFile);
            BufferedInputStream is = new BufferedInputStream(
                    new FileInputStream(file));
            byte[] buffer = new byte[(int) file.length()];
            is.read(buffer);
            is.close();

            template = new String(buffer);

            // Llenar campos del template
            body = MessageFormat.format(template, templateValues);

            body = this.getFormatedBody(body);

            log.logp(Level.FINE, CLASS_NAME, METHOD_NAME, body);

            Address[] to = new Address[address_to.length];
            for (int i = 0; i < to.length; i++) {
                to[i] = new InternetAddress(address_to[i].trim() + "@ford.com");
            }

            this.sendMail(from, to, subject, body);

        } catch (Exception e) {
            log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, e.getMessage(), e);
        }

        log.exiting(CLASS_NAME, METHOD_NAME);
    }

    /**
     * Enviar un mail usando javax.mail.Transport
     * 
     * @param from
     * Remitente. Se usa el usuario de la base si se pasa null.
     * @param address_to
     * Destinatario(s)
     * @param address_cc
     * Destinatario(s) copiados
     * @param subject
     * Asunto
     * @param body
     * Cuerpo del mail
     */
    private void sendMail(String from, Address[] address_to, String subject,
                          String body) {
        String METHOD_NAME = "sendMail";
        log.entering(CLASS_NAME, METHOD_NAME);

        Properties props = System.getProperties();

        // smtp server initialization
        // props.put("mail.smtp.host", ReConfigProvider.getSmtpServer());
        MimeMessage message = new MimeMessage(Session.getDefaultInstance(props,
                null));

        try {
            if (from == null) {
                // usar el usuario de la base
                // O Usuario que se logeo?
                // from = UserUpdate.getUserUpdate();
            }

            // first part (the header)
            message.setFrom(new InternetAddress(from));
            message.addRecipients(MimeMessage.RecipientType.TO, address_to);
            message.setSubject(subject);

            // second part (the body)
            MimeMultipart multipart = new MimeMultipart();
            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setContent(body, "text/html");

            // add it
            multipart.addBodyPart(messageBodyPart);

            // String filepath =
            // ReConfigProvider.getAppPath()+File.separator+"mail"+File.separator+"LogoFord.gif";
            String filepath = File.separator + "mail" + File.separator
                    + "LogoFord.gif";
            // third part (the image)
            messageBodyPart = new MimeBodyPart();

            DataSource fds = new FileDataSource(filepath);
            messageBodyPart.setDataHandler(new DataHandler(fds));
            messageBodyPart.setHeader("Content-ID", "<image>");

            // add it
            multipart.addBodyPart(messageBodyPart);

            // put everything together
            message.setContent(multipart);

            // send mail
            Transport.send(message);

            log.logp(Level.FINE, CLASS_NAME, METHOD_NAME, "Mail sent");
        } catch (MessagingException mexcep) {
            log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME,
                    "MessagingException: ", mexcep);
        }

        log.exiting(CLASS_NAME, METHOD_NAME);
    }

    /**
     * Aplicar formato html a un texto, incluyendo el tag para el Logo Ford.
     * Cada linea se termina con un tag &lt;br&gt;
     * 
     * @param msg
     * Texto a formatear
     * @return Texto en formato html
     */
    private String getFormatedBody(String msg) {
        String METHOD_NAME = "getFormatedBody";

        log.entering(CLASS_NAME, METHOD_NAME);

        BufferedReader br = new BufferedReader(new StringReader(msg));

        StringBuffer htmlBody = new StringBuffer();
        String linea = null;

        htmlBody.append("<html><body><img align='middle' src='cid:image'>");

        try {
            while ((linea = br.readLine()) != null) {
                htmlBody.append(linea);
                // new line
                htmlBody.append("<br>\n");
            }
        } catch (IOException ioex) {
            log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "IOException: ",
                    ioex);
        }

        htmlBody.append("</body></html>");

        log.exiting(CLASS_NAME, METHOD_NAME);
        return htmlBody.toString();
    }

    /**
     * Enviar mail de reporte de error, usando el template exceptionReport.txt
     * 
     * @param sistema
     * Sistema de origen del archivo
     * @param secuencia
     * Nro. de secuencia de origen
     * @param errorMsg
     * Mensaje de error
     */
    // public void sendExceptionMail(String sistema, Long secuencia, String
    // errorMsg) {
    // String METHOD_NAME = "sendExceptionMail";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mail"+sistema),
    // subject = "Remito Electronico";
    // Object templateParams[] = new Object[]{sistema, secuencia, errorMsg};
    //            
    // this.sendMail(null, cds, subject, "errorArchivoEntrada.txt",
    // templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    // }
    /**
     * Enviar mail de reporte de error, usando el template exceptionReport.txt
     * 
     * @param sistema
     * Sistema de origen del archivo
     * @param secuencia
     * Nro. de secuencia de origen
     * @param errorMsg
     * Mensaje de error
     * @param remitos
     * Lista de remitos que fallaron
     */
    // public void sendExceptionMail(String sistema, Long secuencia, String
    // errorMsg, List remitos) {
    // String METHOD_NAME = "sendExceptionMail";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mail"+sistema),
    // subject = "Remito Electronico",
    // styles = "<style type='text/css'>.green {color: green;} .red{color:
    // red;}</style>";
    //
    // StringBuffer remitosParam = new StringBuffer();
    // Iterator it = remitos.iterator();
    // while(it.hasNext()) {
    // Tmkt402RemitoelecRemito remito = (Tmkt402RemitoelecRemito)it.next();
    // remitosParam.append("<span class='");
    //
    // if ("NO".equals(remito.getMkt402Procesado())) {
    // remitosParam.append("red");
    // }
    // else {
    // remitosParam.append("green");
    // }
    // remitosParam.append("'>");
    // remitosParam.append(remito.getMkt402Tipo());
    // remitosParam.append(' ');
    // remitosParam.append(remito.getMkt402Prefijo().toString());
    // remitosParam.append(' ');
    // remitosParam.append(remito.getMkt402Numero().toString());
    // remitosParam.append("</span>");
    // remitosParam.append('\n');
    // }
    //            
    // Object templateParams[] = new Object[]{sistema, secuencia, errorMsg,
    // remitosParam.toString(), styles};
    //            
    // this.sendMail(null, cds, subject, "errorEnvioRemitos.txt",
    // templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    // }
    /**
     * Enviar mail de reporte de error de conexion, usando el template
     * errorConexion.txt
     * 
     * @param sistema
     * Sistema de origen del archivo
     * @param secuencia
     * Nro. de secuencia de origen
     * @param errorMsg
     * Mensaje de error
     */
    // public void sendMailErrorConexion(String errorMsg) {
    // String METHOD_NAME = "sendMailErrorConexion";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mailAplic"),
    // subject = "Remito Electronico";
    // Object templateParams[] = new Object[]{errorMsg, new MkDate()};
    //            
    // this.sendMail(null, cds, subject, "errorConexion.txt", templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    // }
    // public void sendMailErrorUsuario() {
    // String METHOD_NAME = "sendMailErrorUsuario";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mailUserAdm"),
    // subject = "Remito Electronico - Administracion de Password - URGENTE";
    //
    // String errorMsg = "Por favor autorizar el cambio de password de conexion
    // a Rentas para continuar con la transmision de files al organismo
    // fiscal.<br><br>Gracias.";
    //
    //
    // Object templateParams[] = new Object[]{errorMsg, new MkDate()};
    //            
    // this.sendMail(null, cds, subject, "errorConexion.txt", templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    // }
    // public void sendMailSecuenciasPerdidas(String sistema, List secuencias) {
    // String METHOD_NAME = "sendMailSecuenciasPerdidas";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mail"+sistema),
    // subject = "Remito Electronico";
    // String secString="";
    //
    // if (!secuencias.isEmpty()) {
    // Iterator it = secuencias.iterator();
    // secString = it.next().toString();
    // while(it.hasNext()) {
    // secString+=" "+it.next().toString();
    // }
    // }
    //            
    // Object templateParams[] = new Object[]{secString, sistema};
    //            
    // this.sendMail(null, cds, subject, "secuenciasPerdidas.txt",
    // templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    // }
    // public void sendMailSecuenciaRecuperada(String sistema, Long secuencia) {
    // String METHOD_NAME = "sendMailSecuenciaRecuperada";
    // log.entering(CLASS_NAME, METHOD_NAME);
    // PropertyManager propMgr = PropertyManager.getInstance();
    //        
    // try {
    // String cds =
    // propMgr.getChildGroup("RentasConfig").getString("mail"+sistema),
    // subject = "Remito Electronico";
    //
    // Object templateParams[] = new Object[]{secuencia.toString(), sistema};
    //            
    // this.sendMail(null, cds, subject, "secuenciaRecuperada.txt",
    // templateParams);
    // }
    // catch(PropertyException e) {
    // log.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "No se pudo enviar el
    // mail", e);
    // }
    //        
    // log.exiting(CLASS_NAME, METHOD_NAME);
    //        
    // }
}
